package cn.zqy.demo2.day07.WaitAndWake;

/**
 *  生产者(包子铺)类:是一个线程类,可以继承Thread
 * 	设置线程任务(run):生产包子
 * 	对包子的状态进行判断
 * 	true:有包子
 * 		包子铺调用wait方法进入等待状态
 * 	false:没有包子
 * 		包子铺生产包子
 * 		增加一些趣味性:交替生产两种包子
 * 			有两种状态(i%2==0)
 * 		包子铺生产好了包子
 * 		修改包子的状态为true有
 * 		唤醒吃货线程,让吃货线程吃包子
 *
 * 	注意:
 * 	    包子铺线程和吃货线程关系-->通信(互斥)
 * 	    必须同时同步技术保证两个线程只能有一个在执行
 * 	    锁对象必须保证唯一,可以使用包子对象作为锁对象
 * 	    包子铺类和吃货的类就需要把包子对象作为参数传递进来
 * 	        1.需要在成员位置创建一个包子变量
 * 	        2.使用带参数构造方法,为这个包子变量赋值
 * */
public class BaoZiPu extends Thread{
    //1.需要在成员位置创建一个包子变量
    private BaoZi bz;

    //2.使用带参数构造方法,为这个包子变量赋值
    public BaoZiPu (BaoZi bz) {
        this.bz = bz;
    }
    @Override
    //设置线程任务(run):生产包子
    public void run() {
        //定义一个变量
        int count = 0;

        //让包子铺循环生产包子
        for (int i = 0; i < 5; i++) {

            //必须同时同步技术保证两个线程只能有一个在执行
            synchronized (bz) {
                //包子铺调用wait方法进入等待状态【有，则等待】
                if (bz.isFlag()) {
                    try {
                        bz.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } else {

                    if (count % 2 == 0) {
                        bz.setPi("薄皮");
                        bz.setXian("猪肉大葱");
                    } else {
                        bz.setPi("皮冰");
                        bz.setXian("牛肉三鲜");
                    }
                    System.out.println("包子铺正在生产：" + bz.getPi() + bz.getXian() + "包子");
                    //生产包子需要3秒钟
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    count++;
                    bz.setFlag(true);  //修改包子的状态为true有
                    bz.notify();  //唤醒吃货线程,让吃货线程吃包子
                    System.out.println("包子铺已经生产好了，" + bz.getPi() + bz.getXian() + "包子，吃货开吃了");
                }
            }
        }
    }
}
